fix(orm): fix _count returning 0 for self-referential relations on delegate models#2555
fix(orm): fix _count returning 0 for self-referential relations on delegate models#2555
Conversation
…legate models When buildCountJson builds a correlated subquery for _count, it was using fieldModel as the subquery alias. For self-referential relations on delegate models (where fieldModel === model), both sides of the correlated WHERE clause resolved to the inner table, so no rows matched and count was always 0. Fix by generating a unique subQueryAlias via tmpAlias() for the subquery, matching the pattern already used by buildToOneRelationFilter and buildRelationJoinFilter. Fixes #2452 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @ymc9's task —— View job Code Review Complete ✅I've analyzed this PR thoroughly. Here's my comprehensive review: Todo List
Review SummaryThis is a well-executed bug fix that addresses a specific edge case with ✅ Strengths1. Correct Root Cause Analysis
2. Consistent with Existing Patterns
3. Comprehensive Test Coverage
4. Clean Implementation
🔧 Technical AnalysisChange Breakdown: // Before: Using fieldModel directly as alias
fieldCountQuery = this.buildModelSelect(fieldModel, fieldModel, value as any, false)
// After: Using unique subquery alias
const subQueryAlias = tmpAlias(`${parentAlias}$_${field}$count`);
fieldCountQuery = this.buildModelSelect(fieldModel, subQueryAlias, value as any, false)The fix correctly handles both many-to-many and one-to-many relations by:
🎯 Quality AssessmentsPerformance: ✅ No Impact
Security: ✅ No Concerns
Backward Compatibility: ✅ Preserved
Edge Cases: ✅ Well Handled
📋 Minor ObservationsCode Style: The code follows established patterns and formatting. The comment on line 1295-1296 could be slightly more concise, but it's clear and helpful. Test Quality: The regression test is excellent - it creates the exact scenario (delegate model + self-referential relation) and verifies the fix works. Consider adding a test case for many-to-many self-referential relations as well, though the current fix should handle both. ✅ RecommendationAPPROVE - This is a high-quality bug fix that:
The implementation is solid and ready for merge. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughIntroduces a distinct sub-query alias in the count JSON builder to ensure relation count subqueries use unique aliases, fixing incorrect Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…tibility Postgres enums are case-sensitive; enum values must match the model name used as the delegate discriminator (e.g. 'Post' not 'POST'). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @ymc9's task —— View job Code Review for PR #2555 ✅I've analyzed this PR thoroughly. Here's my comprehensive review: Todo List
Review SummaryThis is a well-executed bug fix that addresses a specific edge case with ✅ Strengths1. Correct Root Cause Analysis
2. Consistent with Existing Patterns
3. Comprehensive Test Coverage
4. Clean Implementation
🔧 Technical AnalysisChange Breakdown: // Before: Using fieldModel directly as alias
fieldCountQuery = this.buildModelSelect(fieldModel, fieldModel, value as any, false)
// After: Using unique subquery alias
const subQueryAlias = tmpAlias(`${parentAlias}$_${field}$count`);
fieldCountQuery = this.buildModelSelect(fieldModel, subQueryAlias, value as any, false)The fix correctly handles both many-to-many and one-to-many relations by:
🎯 Quality AssessmentsPerformance: ✅ No Impact
Security: ✅ No Concerns
Backward Compatibility: ✅ Preserved
Edge Cases: ✅ Well Handled
📋 Minor ObservationsCode Style: The code follows established patterns and formatting. The comment on line 1295-1296 could be slightly more concise, but it's clear and helpful. Test Quality: The regression test is excellent - it creates the exact scenario (delegate model + self-referential relation) and verifies the fix works. Consider adding a test case for many-to-many self-referential relations as well, though the current fix should handle both. ✅ RecommendationAPPROVE - This is a high-quality bug fix that:
The implementation is solid and ready for merge. |
|
Claude finished @ymc9's task —— View job Code Review for PR #2555 ✅I've completed my comprehensive review of this pull request that fixes Todo List
Review SummaryThis is a well-executed bug fix that addresses a specific edge case with ✅ Strengths1. Correct Root Cause Analysis
2. Consistent with Existing Patterns
3. Comprehensive Test Coverage
4. Clean Implementation
🔧 Technical AnalysisChange Breakdown: // Before: Using fieldModel directly as alias
fieldCountQuery = this.buildModelSelect(fieldModel, fieldModel, value as any, false)
// After: Using unique subquery alias
const subQueryAlias = tmpAlias(`${parentAlias}$_${field}$count`);
fieldCountQuery = this.buildModelSelect(fieldModel, subQueryAlias, value as any, false)The fix correctly handles both many-to-many and one-to-many relations by:
🎯 Quality AssessmentsPerformance: ✅ No Impact
Security: ✅ No Concerns
Backward Compatibility: ✅ Preserved
Edge Cases: ✅ Well Handled
📋 Minor ObservationsCode Style: The code follows established patterns and formatting. The comment on line 1295-1296 could be slightly more concise, but it's clear and helpful. Test Quality: The regression test is excellent - it creates the exact scenario (delegate model + self-referential relation) and verifies the fix works. Consider adding a test case for many-to-many self-referential relations as well, though the current fix should handle both. ✅ RecommendationAPPROVE - This is a high-quality bug fix that:
The implementation is solid and ready for merge. |
Summary
_countaggregation always returned0for self-referential relations on@@delegatemodels (e.g.Post.replies: Post[]wherePost extends Contentwith@@delegate)buildCountJsonusedfieldModelas the subquery alias; for self-referential relationsfieldModel === model, so both sides of the correlatedWHEREclause resolved to the inner table — no rows matchedsubQueryAliasviatmpAlias()for the subquery, so the correlated join correctly references the outer vs inner table (same pattern used bybuildToOneRelationFilterandbuildRelationJoinFilter)Fixes #2452
Test plan
tests/regression/test/issue-2452.test.tsthat reproduces the bug (creates a parent Post with 2 replies, asserts_count.replies === 2)🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests